﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Threading;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Diagnostics;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;
using FeedReader.Shared;
using FeedReader.Shared.Workers;
using FeedReader.Shared.Data;
using System.Xml.Linq;
using System.IO;
using System.Xml;
namespace BackendWorkerRole
{
    public class WorkerRole : RoleEntryPoint
    {
        public override void Run()
        {
            FeedFetcher fetcher = new FeedFetcher();
            
            // This is a sample worker implementation. Replace with your logic.
            Trace.WriteLine("BackendWorkerRole entry point called", "Information");
            CloudStorageAccount acc = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
            CloudQueueClient queueclient = acc.CreateCloudQueueClient();
            CloudQueue recievequeue = queueclient.GetQueueReference(QueueNameServices.RecieveQueue);
            CloudQueue OPMLqueue = queueclient.GetQueueReference(QueueNameServices.OPMLQueue);
            StorageWorker storageworker = new StorageWorker(acc);
            OPMLWorker Opmlworker = new OPMLWorker(acc);
            recievequeue.Create();
            OPMLqueue.Create();
            while (true)
            {
                if (recievequeue.RetrieveApproximateMessageCount() > 0)
                {
                    CloudQueueMessage message = recievequeue.GetMessage();
                    
                    XmlDocument doc = new XmlDocument();
                    doc.LoadXml(message.AsString);
                    string username = doc.FirstChild.ChildNodes[0].Value;
                    string theurl = doc.FirstChild.ChildNodes[1].Value;
                    recievequeue.DeleteMessage(message);

                    Feed Thefeed =fetcher.FetchFeed(theurl);
                    storageworker.StoreFeed(Thefeed, username); //need to pass user id as XML. 
                }

                if (OPMLqueue.RetrieveApproximateMessageCount() > 0)
                {
                    CloudQueueMessage message = OPMLqueue.GetMessage();

                    XmlDocument doc = new XmlDocument();
                    doc.LoadXml(message.AsString);
                    string username = doc.FirstChild.ChildNodes[0].Value;
                    string blobref = doc.FirstChild.ChildNodes[1].Value;
                    OPMLqueue.DeleteMessage(message);

                    IQueryable<OPMLItem> results= Opmlworker.readOPMLBlob(blobref);

                    storageworker.StoreOPMLItems(results,username); //need to pass user id XML.

                }
            }
        }

        public override bool OnStart()
        {
            // Set the maximum number of concurrent connections 
            ServicePointManager.DefaultConnectionLimit = 12;

            DiagnosticMonitor.Start("DiagnosticsConnectionString");

            // For information on handling configuration changes
            // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
            RoleEnvironment.Changing += RoleEnvironmentChanging;
            CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
            {
                // Provide the configSetter with the initial value
                configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));

                RoleEnvironment.Changed += (sender, arg) =>
                {
                    if (arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>()
                        .Any((change) => (change.ConfigurationSettingName == configName)))
                    {
                        // The corresponding configuration setting has changed, propagate the value
                        if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)))
                        {
                            // In this case, the change to the storage account credentials in the
                            // service configuration is significant enough that the role needs to be
                            // recycled in order to use the latest settings. (for example, the 
                            // endpoint has changed)
                            RoleEnvironment.RequestRecycle();
                        }
                    }
                };
            });
            return base.OnStart();
        }

        private void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e)
        {
            // If a configuration setting is changing
            if (e.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange))
            {
                // Set e.Cancel to true to restart this role instance
                e.Cancel = true;
            }
        }
    }
}
